package edu.scau.ojforwarder.util;

import edu.scau.ojforwarder.bean.HduError;
import edu.scau.ojforwarder.bean.HduStatus;
import edu.scau.ojforwarder.bean.IError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class HduStatusManager {

    @Autowired
    private HduClient hduClient;

    private Map<String, HduStatus> runIdStatusMap = new HashMap<>();

    private Map<String, HduStatus> submissionIdStatusMap = new HashMap<>();

    private Logger logger = LoggerFactory.getLogger(HduStatusManager.class);

    public synchronized void addStatus(String submissionId, HduStatus status) {
        status.setSubmissionId(submissionId);
        submissionIdStatusMap.put(submissionId, status);
    }

    public synchronized HduStatus getStatus(String submissionId) {
        try {
            return (HduStatus) submissionIdStatusMap.get(submissionId).clone();
        } catch (Exception e) {
            logger.error("获取结果失败。", e);
            return null;
        }
    }

    public synchronized void addAssociation(String runId, String submissionId) {
        HduStatus status = submissionIdStatusMap.get(submissionId);
        status.setRunId(runId);
        runIdStatusMap.put(runId, status);
    }

    public synchronized void updateStatus(List<HduStatus> statusList) {
        for (HduStatus status : statusList) {
            HduStatus s = runIdStatusMap.get(status.getRunId());
            if (s != null) {
                s.setSubmitTime(status.getSubmitTime());
                s.setStatus(status.getStatus());
                s.setProId(status.getProId());
                s.setExeTime(status.getExeTime());
                s.setExeMemory(status.getExeMemory());
                s.setLanguage(status.getLanguage());
                if (status.getStatus().startsWith("Runtime Error"))
                    s.setResult(5);
                else {
                    switch (status.getStatus()) {
                        case "Accepted": s.setResult(0); break;
                        case "Presentation Error": s.setResult(1); break;
                        case "Time Limit Exceeded": s.setResult(2); break;
                        case "Memory Limit Exceeded": s.setResult(3); break;
                        case "Wrong Answer": s.setResult(4); break;
                        case "Output Limit Exceeded": s.setResult(6); break;
                        case "Compilation Error": s.setResult(7); break;
                    }
                }
                if (s.getStatus().equals("Compilation Error") && s.getCompileError() == null)
                    s.setCompileError(hduClient.getCompileError(s.getCid(), s.getRunId()));
            }
        }
    }

    public void updateStatus(String cid) {
        try {
            List<HduStatus> statusList = hduClient.getStatus(cid, true, true);
            if (statusList != null) {
                updateStatus(statusList);
            }
        } catch (Exception e) {
            logger.error("更新结果失败。", e);
        }
    }

    /**
     * 设置出错原因，只用于提交代码时产生的错误
     * @param submissionId
     * @param error
     */
    public synchronized void setError(String submissionId, IError error) {
        HduStatus status = submissionIdStatusMap.get(submissionId);
        status.setStatus(HduStatus.SUBMIT_FAILED);
        status.setError((HduError) error);
        status.setResult(21);
    }
}
